; messages
(define-constant *G-TransitNode-starter*  0x01)
(define-constant *G-TransitNode-input*    0x02)
(define-constant *G-TransitNode-next*     0x03)

; make-TransitNode todo
(define (make-TransitNode self starter input next)
	(lambda (message)
		(case message
			((*G-TransitNode-starter*) starter)
			((*G-TransitNode-input*) input)
            ((*G-TransitNode-next*) next)
			; todo
			(else ()))))

; messages
(define-constant *M-TransitTable-put*    0x01)
(define-constant *M-TransitTable-get*    0x02)

; make-TransitTable
(define (make-TransitTable self hash-table)
	(define hash-code-state (lambda (state) (car state)))
	(define (put key value) (ask hash-table *M-HashTable-put* key value hash-code-state))
	(define (get key) (ask hash-table *M-HashTable-gut* key hash-code-state))
	(lambda (message)
		(case message
			((*M-TransitTable-put*)
				(lambda (current-state node)
					(let ((v (get current-state)))
						(if (null? v) (put current-state node)
							(put current-state (list v node))))))
			((*M-TransitTable-get*)
				(lambda (current-state starter input)
					(let ((v (get current-state)))
						(do ((e (car v) (cdr e)))
							(null? e)
							(if (and (eqv (car starter) (car (ask e *G-TransitNode-starter*))) 
									(match-statement input (ask e *G-TransitNode-input*)))
								e)))))
			(else ()))))


(define (transit table starter state input assoc-list)
	(cond ((or (null? state) (null? input)) *nil*)
		((statement-symbol? input)
			(ask-chain table (*M-TransitTable-get* state starter input) (*G-TransitNode-next*)))
		((statement-argument? input)
			(let ((node (ask table *M-TransitTable-get* state starter input)))
				(assoc assoc-list (ask-chain node (*G-TransitNode-input*) (*M-Statement-argument-name*)) input)
				(ask node *G-TransitNode-next*)))
		(else *nil*)))

; transit-table
(define transit-table (create-TransitTable (create-HashTable)))

